import Glibc

class Timer {
    private let CLOCK_REALTIME = 0
    private var start_timespec = timespec()
    private var end_timespec = timespec()
    private var time_spec = timespec()
    func start() {
        clock_gettime(Int32(CLOCK_REALTIME),&start_timespec)
    }
    
    func stop() -> Double {
        clock_gettime(Int32(CLOCK_REALTIME),&end_timespec)
        let start_time = Double(start_timespec.tv_sec * 1_000_000 + start_timespec.tv_nsec / 1_000)
        let end_time = Double(end_timespec.tv_sec * 1_000_000 + end_timespec.tv_nsec / 1_000)
        let time = end_time - start_time
        return time / 1_000
    }
    func getTime() -> Double {
        clock_gettime(Int32(CLOCK_REALTIME),&time_spec)
        return Double(time_spec.tv_sec * 1_000_000 + time_spec.tv_nsec / 1_000)
    }
}

let timer = Timer()

func complexFloatNumeric() -> Double {
    let count = 5000000
    let testArray = [2.3, 4.6, 5.2, 5.5, 6.1, 6.7, 7.4, 7.6, 7.886, 8.2, 9.11, 10.02, 33.2];
    var res = 5
    timer.start()
    let testArrayLength = testArray.count
    for i in 1..<count {
        let value = testArray[i % res & (testArrayLength - 1)]
        var tmp = 0
        var low = 0
        var high = testArrayLength - 1
        var middle = high >> 1
        while low <= high {
            let test = testArray[middle]
            if test > value {
                high = middle - 1
            } else if test < value {
                low = middle + 1
            } else {
                tmp = middle
                break
            }
            middle = (low + high) >> 1
        }
        res += tmp
    }
    let time = timer.stop()
    print(res)
    print("Numerical Calculation - ComplexFloatNumeric:\t"+String(time)+"\tms");
    return time
}
func runComplexFloatNumeric()->Double{
    return complexFloatNumeric()
}

_ = runComplexFloatNumeric()
